package com.club.football.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.club.football.common.UserHolder;
import com.club.football.dto.EventsDetailSaveDto;
import com.club.football.dto.PageDto;
import com.club.football.entity.*;
import com.club.football.mapper.EventsDetailMapper;
import com.club.football.req.EventsDetailReq;
import com.club.football.service.*;
import com.club.football.utils.BeanUtils;
import com.club.football.utils.R;
import com.club.football.vo.EventsDetailListVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.club.football.common.CommonConstants.*;

/**
 * 实施匹配详细信息服务
 *
 * @author 1
 * @date 2024/01/09
 */
@Service
@AllArgsConstructor
public class EventsDetailServiceImpl extends ServiceImpl<EventsDetailMapper, EventsDetail> implements EventsDetailService {
    private final EventsService eventsService;
    private final EventsTeamsService eventsTeamsService;
    private final PlayerService playerService;
    private final ScheduleService scheduleService;

    @Override
    public R<Page<EventsDetail>> eventsDetailPage(PageDto<EventsDetail> pageDto, EventsDetailReq eventsDetailReq) {
        //赛事id
        Long eventsId = eventsDetailReq.getEventsId();
        Long scheduleId = eventsDetailReq.getScheduleId();
        Long playerId = eventsDetailReq.getPlayerId();
        lambdaQuery().eq(eventsId != null, EventsDetail::getEventsId, eventsId).eq(scheduleId != null, EventsDetail::getScheduleId, scheduleId).eq(playerId != null, EventsDetail::getPlayerId, playerId).page(pageDto);
        return R.ok(pageDto, GET_INFO_OK);
    }

    @Override
    public R<String> eventsDetailSave(EventsDetailSaveDto saveDto) {
        EventsDetail eventsDetail = BeanUtils.copier(saveDto, new EventsDetail());
        Long userId = UserHolder.getUser().getUserId();
        eventsDetail.setUpdateBy(userId);
        Player player = playerService.getById(eventsDetail.getPlayerId());
        eventsDetail.setTeamId(player.getTeamId());
        if (eventsDetail.getEventsDetailId() != null) {
            updateById(eventsDetail);
            return R.ok(EDIT_OK_MSG);
        }
        eventsDetail.setCreateBy(userId);
        save(eventsDetail);
        return R.ok(SAVE_OK_MSG);
    }

    @Override
    public R<EventsDetailListVo> eventsList(EventsDetailReq eventsDetailReq) {
        Long eventsId = eventsDetailReq.getEventsId();
        Long scheduleId = eventsDetailReq.getScheduleId();
        Long playerId = eventsDetailReq.getPlayerId();

        String key = getKey(eventsDetailReq);
        switch (key) {
            case "001":
                return get001(playerId, key);
            case "010":
                return get010(scheduleId, key);
            case "011":
                return get011(scheduleId, playerId, key);
            case "100":
                return get100(eventsId, key);
            case "101":
                return get101(eventsId, playerId, key);
            case "110":
                return get110(scheduleId, key);
            case "000":
            default:
                return get000(key);
        }
    }

    private R<EventsDetailListVo> get011(Long scheduleId, Long playerId, String key) {
        EventsDetailListVo eventsDetailListVo = new EventsDetailListVo(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
        Player player = playerService.getById(playerId);
        Long teamId = player.getTeamId();
        Schedule schedule = scheduleService.getById(scheduleId);
        Long eventsId = schedule.getEventsId();
        List<EventsTeams> eventsTeamsList = eventsTeamsService.lambdaQuery().eq(EventsTeams::getEventsId, eventsId)
                .eq(EventsTeams::getTeamId, teamId).list();
        if (CollUtil.isEmpty(eventsTeamsList)) {
            return R.ok(eventsDetailListVo, GET_INFO_OK);
        }
        Events events = eventsService.getById(eventsId);
        eventsDetailListVo.setPlayerList(Collections.singletonList(player));
        eventsDetailListVo.setEventsList(Collections.singletonList(events));
        return R.ok(eventsDetailListVo, GET_INFO_OK);
    }

    private R<EventsDetailListVo> get010(Long scheduleId, String key) {
        return get110(scheduleId, key);
    }

    private R<EventsDetailListVo> get001(Long playerId, String key) {
        EventsDetailListVo eventsDetailListVo = new EventsDetailListVo(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
        Player player = playerService.getById(playerId);
        Long teamId = player.getTeamId();
        List<Long> eventIds = eventsTeamsService.lambdaQuery()
                .eq(EventsTeams::getTeamId, teamId).list()
                .stream().map(EventsTeams::getEventsId).collect(Collectors.toList());
        List<Schedule> scheduleList = scheduleService.lambdaQuery().in(Schedule::getEventsId, eventIds).list();
        List<Player> playerList = getPlayerListBySchedule(scheduleList);
        List<Events> eventsList = eventsService.list();
        eventsDetailListVo.setEventsList(eventsList);
        eventsDetailListVo.setScheduleList(scheduleList);
        eventsDetailListVo.setPlayerList(playerList);
        return R.ok(eventsDetailListVo, GET_INFO_OK);
    }

    private R<EventsDetailListVo> get110(Long scheduleId, String key) {
        EventsDetailListVo eventsDetailListVo = new EventsDetailListVo(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
        Schedule schedule = scheduleService.getById(scheduleId);
        Events events = eventsService.getById(schedule.getEventsId());
        List<Player> playerList = getPlayerListBySchedule(Collections.singletonList(schedule));

        List<Schedule> scheduleList = scheduleService.list();
        eventsDetailListVo.setEventsList(Collections.singletonList(events));
        eventsDetailListVo.setScheduleList(scheduleList);
        eventsDetailListVo.setPlayerList(playerList);
        return R.ok(eventsDetailListVo, GET_INFO_OK);
    }

    private R<EventsDetailListVo> get000(String key) {
        List<Events> eventsList = eventsService.list();
        List<Schedule> scheduleList = scheduleService.list();
        List<Player> playerList = playerService.list();
        EventsDetailListVo eventsDetailListVo = new EventsDetailListVo(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
        eventsDetailListVo.setEventsList(eventsList);
        eventsDetailListVo.setPlayerList(playerList);
        eventsDetailListVo.setScheduleList(scheduleList);
        return R.ok(eventsDetailListVo, GET_INFO_OK);
    }

    private R<EventsDetailListVo> get100(Long eventsId, String key) {
        EventsDetailListVo eventsDetailListVo = new EventsDetailListVo(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
        List<Schedule> scheduleList = scheduleService.lambdaQuery().eq(Schedule::getEventsId, eventsId).list();

        List<Events> eventsList = eventsService.list();
        eventsDetailListVo.setEventsList(eventsList);
        eventsDetailListVo.setScheduleList(scheduleList);
        eventsDetailListVo.setPlayerList(getPlayerListBySchedule(scheduleList));
        return R.ok(eventsDetailListVo, GET_INFO_OK);
    }

    private R<EventsDetailListVo> get101(Long eventsId, Long playerId, String key) {
        EventsDetailListVo eventsDetailListVo = new EventsDetailListVo(key, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
        Player player = playerService.getById(playerId);
        List<Schedule> scheduleList = scheduleService.lambdaQuery().eq(Schedule::getEventsId, eventsId)
                .and(i -> i.eq(Schedule::getHomeTeamId, player.getTeamId()).or().eq(Schedule::getVisitingTeamId, player.getTeamId()))
                .list();
        List<Events> eventsList = eventsService.list();
        List<Player> playerList = playerService.list();
        eventsDetailListVo.setEventsList(eventsList);
        eventsDetailListVo.setPlayerList(playerList);
        eventsDetailListVo.setScheduleList(scheduleList);
        return R.ok(eventsDetailListVo, GET_INFO_OK);
    }


    /**
     * 获取密钥
     *
     * @param eventsDetailReq 活动详细信息请求
     * @return {@link String}
     */
    private static String getKey(EventsDetailReq eventsDetailReq) {
        String events = eventsDetailReq.getEventsId() == null ? "0" : "1";
        String schedule = eventsDetailReq.getScheduleId() == null ? "0" : "1";
        String player = eventsDetailReq.getPlayerId() == null ? "0" : "1";
        return events + schedule + player;
    }

    private List<Player> getPlayerListBySchedule(List<Schedule> scheduleList) {
        ArrayList<Long> teamIdList = new ArrayList<>();
        for (Schedule schedule : scheduleList) {
            teamIdList.add(schedule.getHomeTeamId());
            teamIdList.add(schedule.getVisitingTeamId());
        }
        if (CollUtil.isEmpty(teamIdList)) {
            return Collections.emptyList();
        }
        return playerService.lambdaQuery().in(Player::getTeamId, teamIdList).list();
    }
}
